#!/usr/bin/env python
#
#       Ships.py
#       
#       Copyright 2009 Ben Davis <its.hip@gmail.com>, Pete Lord <mr.petelord@gmail.com>
#       
#       This program is free software; you can redistribute it and/or modify
#       it under the terms of the GNU General Public License as published by
#       the Free Software Foundation; either version 2 of the License, or
#       (at your option) any later version.
#       
#       This program is distributed in the hope that it will be useful,
#       but WITHOUT ANY WARRANTY; without even the implied warranty of
#       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#       GNU General Public License for more details.
#       
#       You should have received a copy of the GNU General Public License
#       along with this program; if not, write to the Free Software
#       Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
#       MA 02110-1301, USA.

import math
import os
import pygame
import random

import Effects
import Objects
import Options

from Client import Client
client = Client()
        
class Ships(dict):
    def __setitem__(self, i, y):
        y.__setup__()
        dict.__setitem__(self, i, y)
        
    def __setup__(self, player):
        for ship in self.values():
            ship.__setup__(player)
    
    def get_key(self, item):
        for key, element in self.items():
            if element == item:
                return key
        raise KeyError
    
    def values_by_position(self):
        return sorted(self.values(), key=lambda ship: ship.x + ship.y)
    
    def first_ship_with_steam(self):
        for ship in self.values_by_position():
            if ship.steam > 0:
                return ship

class Ship(Objects.Object):
    def __setup__(self):
        Objects.Object.__init__(self, self.x, self.y, self.r)
        self.selected = False
        for weapon in self.weapons:
            weapon.__setup__(self)
    
    def draw_lights(self):
        return self.textures[Options.ZOOM_LEVEL][1][self.r][self.current_frame], pygame.Rect(self.screen_location(), (Options.SPRITE_SIZE[Options.ZOOM_LEVEL], Options.SPRITE_SIZE[Options.ZOOM_LEVEL]))

    def turn(self, amount):
        self.r += amount
                
    def select(self):
        self.selected = True
        
    def deselect(self):
        self.selected = False
        
    def key(self):
        return self.__key__
        
    def hit(self, damage):
        client.game.effects.add_higher(Effects.ShipHit(self))
        client.game.effects.add_higher(Effects.FloatyText((255, 0, 0), "Hit! -" + str(damage), self))
        
    def hit_critical(self, damage):
        client.game.effects.add_higher(Effects.ShipHitCritical(self))
        client.game.effects.add_higher(Effects.FloatyText((200, 200, 0), "Critical hit! -" + str(damage), self))

    def die(self):
        client.game.effects.add_higher(Effects.ShipDeath(self))
        client.game.effects.add_higher(Effects.FloatyText((255, 0, 0), "Blarg ded!", self))

class Pawn(Ship):
    def __setup__(self, player):
        Ship.__setup__(self)
        # animation data goes here. Do we have animation? how many frames? a list of frame timings please.
        self.has_anim = True
        self.anim_frames = 2
        self.anim_frame_times = 10 # 
        self.current_frame = 0 # init.
        self.current_time = random.randint(0, self.anim_frame_times)
        
        if player <= 4:
            self.textures = client.ship_graphics[os.path.join('Data', 'Ships', 'PawnP' + str(player + 1))] # graphics.
        else:
            self.textures = client.ship_graphics[os.path.join('Data', 'Ships', 'TestShip')] # graphics.
            
    def fire(self, weapon):
        self.xy_mod.push(self.weapons[weapon].recoil, self.r + self.weapons[weapon].recoil_direction)
        client.game.effects.add(Effects.PawnCannonA(self, self.weapons[weapon].textures))

class Knight(Ship):
    def __setup__(self, player):
        Ship.__setup__(self)
        # animation data goes here. Do we have animation? how many frames? a list of frame timings please.
        self.has_anim = False
        self.anim_frames = 1
        self.anim_frame_times = 10 # 
        self.current_frame = 0 # init.
        self.current_time = random.randint(0, self.anim_frame_times)
        
        if player <= 4:
            self.textures = client.ship_graphics[os.path.join('Data', 'Ships', 'KnightP' + str(player + 1))] # graphics.
        else:
            self.textures = client.ship_graphics[os.path.join('Data', 'Ships', 'TestShip')]

    def fire(self, weapon):
        self.xy_mod.push(self.weapons[weapon].recoil, self.r + self.weapons[weapon].recoil_direction)
        client.game.effects.add(Effects.PawnCannonA(self, self.weapons[weapon].textures))
        
class King(Ship):
    def __setup__(self, player):
        Ship.__setup__(self)
        self.has_anim = True
        self.anim_frames = 2
        self.anim_frame_times = 10 # 
        self.current_frame = 0 # init.
        self.current_time = random.randint(0, self.anim_frame_times)
        
        if player <= 4:
            self.textures = client.ship_graphics[os.path.join('Data', 'Ships', 'KingP' + str(player + 1))] # graphics.
        else:
            self.textures = client.ship_graphics[os.path.join('Data', 'Ships', 'TestShip')]

    def fire(self, weapon):
        self.xy_mod.push(self.weapons[weapon].recoil, self.r + self.weapons[weapon].recoil_direction)
        client.game.effects.add(Effects.KingCannonS(self, self.weapons[weapon].textures))   
        
    def weapons(self):
        return self.weapons

class MissingNo(Ship):
    def __setup__(self):
        Ship.__setup__(self)
        # animation data goes here. Do we have animation? how many frames? a list of frame timings please.
        self.has_anim = False
        self.anim_frames = 0
        self.anim_frame_times = None
        
        self.weapons = [] # needs to have a testgun added. Like. Not all ships nessecarily have gunz.
        self.textures = client.ship_graphics[os.path.join('Data', 'Ships', 'MissingNo')] # graphics.
